今天要介紹turf.js,
前兩天的網球地圖完成了基本的地圖功能及版面,並在地圖上展示、查詢了GIS資料,今天想進一步對資料做空間資料分析,使用的是turf.js。
turf.js是Mapbox公司提出用來處理空間資料分析的開源函式庫,打開turf.js的說明文件,可以看到其功能非常的多:
要處理空間資料的手段有很多,常見的方法是使用QGIS等軟體做資料處理,也可以使用其他程式語言的函式庫輔助或手刻,而turf.js是一個十分方便輕巧的工具,最棒的是可以用在webGIS中,client端空間資料處理。
至於什麼是空間資料分析呢?主要像是空間資料幾何運算、內插、資料聚合等都算,廢話不多說,我們就先來實作幾個案例。
產生隨機的POI,利用新北市polygon,切出新北市內的POI
首先,先new一個layer
var ramdomLayer = L.geoJson(null, {
pointToLayer: function (feature, latlng) {
return L.marker(latlng, {
icon: L.icon({
iconUrl: "./dist/assets/img/icon-black.png",
iconSize: [36, 36],
iconAnchor: [0, 18]
}),
});
}
});
利用 turf.randomPoint 產生隨機點,設定隨機點的範圍在[121.41, 24.9, 121.8, 25.19] 方框中。
var ramdompts = turf.randomPoint(25, { bbox: [121.41, 24.9, 121.8, 25.19] });
//把成果放入圖層
ramdomLayer.addData(ramdompts);
ramdomLayer.addTo(map);
接著,放入新北市geojson
var ntp = L.geoJson(null);
$.getJSON("./dist/assets/data/ntp.geojson", function (data) {
ntp.addData(data);
});
在沒有屬性欄位的狀態下,我們用幾何取出新北市範圍內的POI
那就使用turf.pointsWithinPolygon~
//ramdompts為前面產生的隨機點
//data為新北市geojson
var ptsWithin = turf.pointsWithinPolygon(ramdompts, data);
//成果為geojson points
ps.成果跟後面一起展示喔
對新北市範圍的POI做距離分群
這邊使用的群聚(cluster)演算法是Kmeans,Kmeans是非監督式學習的分類演算法,
這個演算法要設定分群的數量,流程概述如下:
1.根據預先設定的目標群數n,隨機給n個點作為n群資料的群聚中心
2.資料中距離(空間距離)哪個群聚中心最近,就屬哪類
3.各群以平均值重新計算各群中心點
4.反覆1~3,直到中心點移動量低於設定值或是達到迭代次數而停止
利用turfclustersKmeans為資料作分群,設定分五類:
var clustered_kmeans = turf.clustersKmeans(ptsWithin, { numberOfClusters: 5 });
//結果是geojson points
找出新北市幾何中心及距離該點最近的poi
turf.js有很多幾何的計算,以下是計算Polygon中心點,及找群POI中距離這個中心點最近的一個,
直接看程式碼:
//中心
//data是新北市polygon geojson
var center = turf.center(data);
L.geoJson(center).addTo(map).bindPopup('這是新北幾何中心').openPopup();
最短距離:
var nearest = turf.nearestPoint(center, ptsWithin);
L.geoJson(center).addTo(map).bindPopup('這是距離新北中心最近的點').openPopup();
成果:
隨機給定POI(黑色),使用空間選取前
(ps.,另有不同icon顯示中心點及最近點。)
只顯示新北市內的poi,並依空間分佈分群(不同顏色為不同群)
turf.js除了今天介紹的功能,還有很多是在webGIS常用的,例如buffer,intersect等等,很多GIS軟體工具提供的功能,turf.js都可以引用參考,非常方便,另外,turf.js相關介紹也可以參考Kuro大的youtube及投影片喔^^。
明天會繼續介紹turf.js比較進階的空間分析功能,除了今天的基本運算外,希望能多觸及進階的分析方法!
今天的程式碼一樣放在github(day18的commit)。